package com.topisv.tms.service.lpn;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.costants.StorageConstants;
import com.topisv.tms.entity.lpn.LPN;
import com.topisv.tms.repository.lpn.LPNDao;
import com.topisv.tms.service.base.BaseService;
import com.topisv.tms.utils.InitProperties;
import com.topisv.tms.utils.enums.StorageEnum;

/**
 * 容器接口服务器类
 * 容器之间交互接口，可以在此类上提供。
 * 
 * @author zhangpeijun
 * @version [v1.0.4, 2016年5月10日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Component
@Transactional(readOnly = true)
public class LpnStorageService extends BaseService {
    
    private static Logger logger = LoggerFactory.getLogger(LpnStorageService.class);
    
    public final static String CLUSTERS_NUMBER = InitProperties.get("clustersNumber");
    
    private int count = 0;
    
    @Autowired
    private LPNDao lpnDao;
    
    @Autowired
    private LPNService lpnService;
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    private int updateToUseByFlag(String warehouseCode, String type, String updFlag, int num) {
        String sql = "UPDATE lpn t SET t.status = " + StorageConstants.LPN_STATUS_IN_USE
            + " ,t.flag = ? WHERE t.warehouse_code = ? AND t.status = " + StorageConstants.LPN_STATUS_FREE
            + " and t.storage_type = ?  ORDER BY t.id LIMIT ? ";
        return jdbcTemplate.update(sql, new Object[] {updFlag, warehouseCode, type, num});
    }
    
    /**
     * 获取系统唯一值
     * 
     */
    private synchronized String getUnique() {
        if (count == Integer.MAX_VALUE) {
            count = 0;
        }
        return (count++) + CLUSTERS_NUMBER + System.currentTimeMillis();
    }
    
    public List<LPN> getFreeLpn(String warehouseCode, StorageEnum storageEnum, int num) {
        log.info(
            "getFreeLpn Param: warehouseCode = " + warehouseCode + ", storageEnum = " + storageEnum + ", num = " + num);
        Long c = lpnDao.countFreeLpn(warehouseCode, String.valueOf(storageEnum.getType()));
        int count = c.intValue() ;
        if(count > 0){
            String updFlag = getUnique();
            int updCount = updateToUseByFlag(warehouseCode, String.valueOf(storageEnum.getType()), updFlag, num);
            log.info("getFreeLpn update data num = " + updCount);
            return lpnDao.getLpnByFlag(warehouseCode, updFlag);
        } else {
            log.info("Free Lpn  is zero.");
            return null;
        }
    }
    
    /**
     * 绑定LPN
     * 
     * @param warehouseCode
     * @param sStorageEum
     * @param num
     * @return
     */
    public List<LPN> bindLPN(String warehouseCode, StorageEnum sStorageEum, int num) {
		logger.info("bindLPN Param:warehouseCode=" + warehouseCode + ";sStorageEum=" + sStorageEum + ";num=" + num);
		if(warehouseCode.equals("")){
			return null;
		}
		if(num<0){
			return null;
		}
		List<LPN> freeUpList = getFreeLpn(warehouseCode, sStorageEum, num);
		logger.info("getFreeLpn_freeUpList:" + freeUpList);
		String type = String.valueOf(sStorageEum.getType());
		int j = 1;
		LPN lpn;
		int autoAddNum = 0;
		List<LPN> bindLpnList=new ArrayList<LPN>();
		autoAddNum = freeUpList == null ? num : num - freeUpList.size();
		if(freeUpList != null){
			bindLpnList.addAll(freeUpList);
		}
		for (int i = 0; i < autoAddNum; i++) {
			lpn = new LPN();
			List<LPN> lpnNumByWarehouseCodeList = lpnDao.loadLPNNum(warehouseCode);
			j = 1;
			while (true) {
				String lpnNo = new StringBuilder().append(warehouseCode).append("0").append(type)
						.append(lpnNumByWarehouseCodeList.size() + j).toString();
				int checkLpnNum = lpnDao.checkLPN(warehouseCode, lpnNo).size();
				if (checkLpnNum == 0) {
					lpn.setLpnNo(lpnNo);
					break;
				}
				j++;
			}
			lpn.setWarehouseCode(warehouseCode);
			lpn.setOrderNo("");
			lpn.setStatus(StorageConstants.LPN_STATUS_IN_USE);
			lpn.setStorageType(type);
			lpn.setStorageTable(sStorageEum.getTable());
			lpn.setCreateTime(new Date());
			lpn.setLastModifyTime(new Date());
			lpnService.save(lpn);
			bindLpnList.add(lpn);
		}
		logger.info("totalBindLPN_bindLpnList:" + bindLpnList);
		return bindLpnList;
    }
}
